package io.ooad.banking.dd.domain;

import org.dayatang.domain.EntityRepository;
import org.dayatang.domain.InstanceFactory;

import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 银行账户抽象类
 * Created by yyang on 16/9/16.
 */
@Entity
@Table(name = "accounts")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class BankAccount extends AbstractEntity {

    //户主
    private Party owner;

    //帐号
    private String accountNo;

    //开户日期
    private Date openDate;

    public Party getOwner() {
        return owner;
    }

    public void setOwner(Party owner) {
        this.owner = owner;
    }

    public String getAccountNo() {
        return accountNo;
    }

    public void setAccountNo(String accountNo) {
        this.accountNo = accountNo;
    }

    public Date getOpenDate() {
        return openDate;
    }

    public void setOpenDate(Date openDate) {
        this.openDate = openDate;
    }

    /**
     * 存款
     * @param amount
     * @param transactionTime
     */
    void credit(Money amount, Date transactionTime) {

    }

    /**
     * 取款
     * @param amount
     * @param transactionTime
     */
    void debit(Money amount, Date transactionTime) {

    }

    /**
     * 转账
     * @param toAccount
     * @param amount
     * @param transactionTime
     */
    void transferTo(BankAccount toAccount, Money amount, Date transactionTime) {

    }

    /**
     * 获取交易记录，按交易时间排序
     * @return 按时间排序的交易记录列表
     */
    public List<AccountTransaction> getTransactions() {
        return AccountTransaction.findByAccount(this);
    }

    public static Optional<BankAccount> getById(long id) {
        BankAccount result = getRepository()
                .get(BankAccount.class, id);
        return Optional.ofNullable(result);
    }

    public static Optional<BankAccount> getByAccountNo(String accountNo) {
        BankAccount result = getRepository()
                .createCriteriaQuery(BankAccount.class)
                .eq("accountNo", accountNo)
                .singleResult();
        return Optional.ofNullable(result);
    }

    public static List<BankAccount> findByOwner(Party owner) {
        return getRepository()
                .createCriteriaQuery(BankAccount.class)
                .eq("owner", owner)
                .list();
    }

    private static EntityRepository getRepository() {
        return InstanceFactory.getInstance(EntityRepository.class);
    }
}
